import java.util.Date

/**
  * Created by lilei on 2016/11/16.
  */
object Helloworld {
  'x
  """
    在 Scala 中声明变量和常量不一定要指明数据类型，在没有指明数据类型的情况下，其数据类型是通过变量或常量的初始值推断出来的。

    所以，如果在没有指明数据类型的情况下声明变量或常量必须要给出其初始值，否则将会报错。
  """
  val name = "String"//申明常量
  //var factor:Int//只有class才可以没有初始化
  def main(args : Array[String]): Unit = {
    println(1111111)
    delayed(time())
    """
      Scala的解释器在解析函数参数(function arguments)时有两种方式：

      传值调用（call-by-value）：先计算参数表达式的值，再应用到函数内部；
      传名调用（call-by-name）：将未计算的参数表达式直接应用到函数内部

      在进入函数内部前，传值调用方式就已经将参数表达式的值计算完毕，而传名调用是在函数内部进行参数表达式的值计算的。

      这就造成了一种现象，每次使用传名调用时，解释器都会计算一次表达式的值。
      所以函数可作为一个参数
    """
    //------------------------------
    printInt(b=5, a=7);//指定参数名
    //一般情况下函数调用参数，就按照函数定义时的参数顺序一个个传递。但是我们也可以通过指定函数参数名，并且不需要按照顺序向函数传递参数

    //--------------------------------
    printStrings("Runoob", "Scala", "Python");//可变参数

    println( "返回值 : " + addInt() );//默认参数

    println( factorial(0) )//函数嵌套

    val date = new Date
    val logWithDateBound = log(date, _ : String)//偏应用函数

    logWithDateBound("message1" )
    Thread.sleep(1000)
    logWithDateBound("message2" )
    Thread.sleep(1000)
    logWithDateBound("message3" )

    strcat("2")("1")//函数柯里化

    multiplier(1)//闭包是个函数,返回值依赖于声明在函数外部的一个或多个变量。因为它引用到函数外面定义的变量，定义这个函数的过程是将这个自由变量捕获而构成一个封闭的函数。名称源自于通过“捕获”自由变量的绑定对函数文本执行的“关闭”行动。


    var z = new Array[String](3)//声明数组
    var myArray = Array(1,2)//另一种方式，声明数组

    var total =0
    for ( i <- 0 to (myArray.length - 1)) {//遍历数组
      total += myArray(i);
    }

    //闭包的另一个示例
    val a = add(1);
    println(a)
    println(a(10));

    var testList = List(1,2,3)
    testList.filter(x => x>0)//依据testList推断出是Int类型，所以参数类型和括号可以省略
    testList.filter(_> 0)//占位符语法，只要确定参数只出现一次


    println(matchTest(4))//模式匹配，match结构体类似switch
  }
  //function define
  def add(a:Int,b:Int) : Int = {
    return a+b
  }

  def time() = {//这种申明
    println("获取时间，单位为纳秒")
    System.nanoTime

  }
  def delayed( t: => Long ) = {
    println("在 delayed 方法内")
    println("参数： " + t)

  }

  def printInt( a:Int, b:Int ) = {
    println("Value of a : " + a );
    println("Value of b : " + b );
  }

  def printStrings( args:String * ) = {
    var i : Int = 0;
    for( arg <- args ){
      println("Arg value[" + i + "] = " + arg );
      i = i + 1;
    }

  }
  def addInt( a:Int=5, b:Int=7 ) : Int = {
    var sum:Int = 0
    sum = a + b

    return sum
  }

  def factorial(i: Int): Int = {
    def fact(i: Int, accumulator: Int): Int = {
      if (i <= 1)
        accumulator
      else
        fact(i - 1, i * accumulator)
    }
    fact(i, 1)
  }
  var test = (x:Int)=>x+1//匿名函数
  //var test1 : Int = (x:Int)=>x//报错,我估计可能是，:int已经强调了类型
  var test2 : Int = addInt()
  var test3 = addInt()
  println(222)

  def log(date: Date, message: String)  = {//没有return的,可推断出来
    println(date + "----" + message)

  }

  def strcat(s1: String)(s2: String) = {
    s1 + s2
  }


  var factor:Int=1
  val multiplier = (i:Int) => i * factor

  // 定义整型 List
  val x = List(1,2,3,4)

  // 定义 Set
  var x1 = Set(1,3,5,7)

  // 定义 Map
  val x2 = Map("one" -> 1, "two" -> 2, "three" -> 3)

  // 创建两个不同类型元素的元组
  val x3 = (10, "Runoob")

  // 定义 Option
  val x4:Option[Int] = Some(5)

  def test22() {

  }

  def add(more:Int) = (x:Int) =>  x +more//这也是闭包

  def matchTest(x: Int):String = x match {
    case 1 => "one"
    case 2 => "two"
//    case 3 => 1
//    case _ => 1.21
  }


  var list1 = List(1,2)
  var it = Iterator(1,2)
  var it1 = Iterator(list1)//Iterator()是获取对象的迭代器，传进去的整体对象的迭代，所以it1和it不一样

scala多行字符串的表示方法:
val foo = """菜鸟教程
www.runoob.com
www.w3cschool.cc
www.runnoob.com
以上三个地址都能访问"""
柯里化:
//正常定义1  
    def multiple1(x:Int,y:Int) = x*y  
    println(multiple1(2,3))  
    //其中一个函数作为返回值  
    def multiple2(x:Int)=(y:Int)=>x*y  
    println(multiple2(3)(4))  
      
    //柯里化  
    def multiple3AfterCurring(x:Int)(y:Int) = x*y  
    println(multiple3AfterCurring(4)(5)) //必须传递两个参数，否则编译报错

scala list中符号---::

是用于为list拼接，，一般是：单个元素::列表这种形式，list1：：list2那么list1整体被作为list2中元素	

List的map方法	
def map[B](f: (A) => B): List[B]

通过给定的方法将所有元素重新计算



}
